package com.cucn.ingmall.product.service.impl;

import com.alibaba.fastjson.TypeReference;
import com.cucn.common.to.SeckillSkuInfoTO;
import com.cucn.common.utils.R;
import com.cucn.ingmall.product.entity.SkuImagesEntity;
import com.cucn.ingmall.product.entity.SpuInfoDescEntity;
import com.cucn.ingmall.product.feign.SeckillFeignService;
import com.cucn.ingmall.product.service.*;
import com.cucn.ingmall.product.vo.SkuItemSaleAttrVO;
import com.cucn.ingmall.product.vo.SkuItemVO;
import com.cucn.ingmall.product.vo.SpuItemAttrGroupVO;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ThreadPoolExecutor;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cucn.common.utils.PageUtils;
import com.cucn.common.utils.Query;

import com.cucn.ingmall.product.dao.SkuInfoDao;
import com.cucn.ingmall.product.entity.SkuInfoEntity;

import javax.annotation.Resource;


@Service("skuInfoService")
public class SkuInfoServiceImpl extends ServiceImpl<SkuInfoDao, SkuInfoEntity> implements SkuInfoService {
    @Resource
    private SkuInfoDao skuInfoDao;
    @Resource
    private SkuImagesService skuImagesService;
    @Resource
    private SpuInfoDescService spuInfoDescService;
    @Resource
    private AttrGroupService attrGroupService;
    @Resource
    private SkuSaleAttrValueService skuSaleAttrValueService;
    @Resource
    private ThreadPoolExecutor threadPoolExecutor;
    @Resource
    private SeckillFeignService seckillFeignService;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<SkuInfoEntity> page = this.page(
                new Query<SkuInfoEntity>().getPage(params),
                new QueryWrapper<SkuInfoEntity>()
        );

        return new PageUtils(page);
    }

    /**
     * 保存sku的基本信息
     *
     * @param skuInfoEntity sku基本信息对象
     */
    @Override
    public void saveSkuInfo(SkuInfoEntity skuInfoEntity) {
        baseMapper.insert(skuInfoEntity);
    }

    /**
     * sku条件检索
     *
     * @param params 请求参数
     * @return 检索出的分页数据
     */
    @Override
    public PageUtils queryPageByCondition(Map<String, Object> params) {
        QueryWrapper<SkuInfoEntity> wrapper = new QueryWrapper<>();
        /**
         * key: '华为',//检索关键字
         * catelogId: 0,
         * brandId: 0,
         * min: 0,
         * max: 0
         */
        String key = (String) params.get("key");
        if (StringUtils.isNotEmpty(key)) {
            wrapper.and(w -> {
                w.eq("sku_id", key).or().like("sku_name", key);
            });
        }

        String catelogId = (String) (params.get("catelogId"));
        if (StringUtils.isNotEmpty(catelogId) && !"0".equalsIgnoreCase(catelogId)) {
            wrapper.eq("catalog_id", catelogId);
        }

        String brandId = (String) (params.get("brandId"));
        if (StringUtils.isNotEmpty(brandId) && !"0".equalsIgnoreCase(brandId)) {
            wrapper.eq("brand_id", brandId);
        }

        String min = (String) params.get("min");
        String max = (String) params.get("max");
        if (StringUtils.isNotEmpty(min) && StringUtils.isNotEmpty(max)) {
            try {
                BigDecimal minDecimal = new BigDecimal(min);
                BigDecimal maxDecimal = new BigDecimal(max);
                if (maxDecimal.compareTo(new BigDecimal("0")) > 0) {
                    wrapper.between("price", minDecimal, maxDecimal);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        IPage<SkuInfoEntity> page = this.page(
                new Query<SkuInfoEntity>().getPage(params),
                wrapper
        );

        return new PageUtils(page);
    }

    /**
     * 根据skuId查询sku的详细信息到商品详情页
     * 并使用异步编排进行优化查询逻辑
     *
     * @param skuId skuId
     * @return sku详细信息
     */
    @Override
    public SkuItemVO item(Long skuId) throws ExecutionException, InterruptedException {
        SkuItemVO skuItemVO = new SkuItemVO();

        //1.sku基本信息获取 pms_sku_info
        CompletableFuture<SkuInfoEntity> skuInfoEntityCompletableFuture = CompletableFuture.supplyAsync(() -> {
            SkuInfoEntity skuInfoEntity = skuInfoDao.selectById(skuId);
            skuItemVO.setInfo(skuInfoEntity);
            return skuInfoEntity;
        }, threadPoolExecutor);

        //3.sku的所属的spu下的所有销售属性组合信息
        CompletableFuture<Void> saleAttrsFuture = skuInfoEntityCompletableFuture.thenAcceptAsync(res -> {
            List<SkuItemSaleAttrVO> saleAttr = skuSaleAttrValueService.getSaleAttrsBySpuId(res.getSpuId());
            skuItemVO.setSaleAttr(saleAttr);
        }, threadPoolExecutor);

        //4.spu介绍 pms_spu_info_desc
        CompletableFuture<Void> spuInfoDescFuture = skuInfoEntityCompletableFuture.thenAcceptAsync(res -> {
            SpuInfoDescEntity spuInfoDesc = spuInfoDescService.getById(res.getSpuId());
            skuItemVO.setDesp(spuInfoDesc);
        }, threadPoolExecutor);

        //5.获取spu的规格参数信息
        CompletableFuture<Void> attrGroupWithAttrsFuture = skuInfoEntityCompletableFuture.thenAcceptAsync(res -> {
            List<SpuItemAttrGroupVO> groupAttrs = attrGroupService.getAttrGroupWithAttrsBySpuId(res.getSpuId(), res.getCatalogId());
            skuItemVO.setGroupAttrs(groupAttrs);
        }, threadPoolExecutor);

        //2.sku的图片信息 pms_sku_images
        CompletableFuture<Void> skuImagesFuture = CompletableFuture.runAsync(() -> {
            List<SkuImagesEntity> skuImagesList = skuImagesService.getImagesBySkuId(skuId);
            skuItemVO.setImages(skuImagesList);
        }, threadPoolExecutor);

        //3.查询当前sku是否参与秒杀优惠
        CompletableFuture<Void> seckillInfo = CompletableFuture.runAsync(() -> {
            R rSeckillSkuInfo = seckillFeignService.getSkukillInfo(skuId);
            if (rSeckillSkuInfo.getCode() == 0) {
                SeckillSkuInfoTO seckillSkuInfoData = rSeckillSkuInfo.getData(new TypeReference<SeckillSkuInfoTO>() {
                });
                skuItemVO.setSeckillSkuInfo(seckillSkuInfoData);
            }
        }, threadPoolExecutor);

        //等待全部完成
        CompletableFuture<Void> allOf = CompletableFuture.allOf(saleAttrsFuture, spuInfoDescFuture, attrGroupWithAttrsFuture, skuImagesFuture,seckillInfo);
        allOf.get();

        return skuItemVO;
    }

    @Override
    public BigDecimal getSkuPrice(Long skuId) {
        SkuInfoEntity skuInfo = baseMapper.selectById(skuId);
        return skuInfo.getPrice();
    }
}